<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    function Cat(name, color, type) {
        // 实例化对象的属性/方法
        // this.name = name;
        // this.color = color;
        // this.type = type;
        Object.defineProperties(this, {
            name: {
                value: name,
                configurable: true,
                writable: true,
                enumerable: true,
            },
            color: {
                value: color,
                configurable: true,
                writable: true,
                enumerable: true,
            },
            type: {
                value: type,
                configurable: true,
                writable: true,
                enumerable: true,
            }

        })
    }
    // console.dir(Cat);

    // 原型对象
    // Cat.prototype = {constructor}
    Cat.prototype.species = "Cat";
    Cat.prototype.skill = function () {
        console.log("捉老鼠");
    };
    Cat.prototype.call = function () {
        console.log("喵喵");
    };
    Cat.prototype.say = function () {
        // this -> 调用此方法的实例化对象
        console.log(this.name, this.color);
    };


    Object.prototype.a = 1;
    Object.prototype.b = 2;

    // 原型链: 实例化对象在查找属性和方法时的一个链式查找机制

    // 实例化对象自身 =>  构造函数的原型对象          =>       Object的原型对象    
    //     Tom       Cat.prototype(Tom.[[Prototype]])   Object.prototype( Cat.prototype.[[Prototype]])

    var Tom = new Cat("Tom", "black", "黑猫");
    console.log(Tom);



    // hasOwnProperty()   判断某个实例化对象上是否存在某个属性 (只查找实例化对象自身,不查找原型链)
    // console.log(Tom.hasOwnProperty("name"));
    // console.log(Tom.hasOwnProperty("color"));
    // console.log(Tom.hasOwnProperty("type"));
    // console.log(Tom.hasOwnProperty("species"));

    // 拓展
    // in 判断某个属性 是否存在于 某个实例化对象的原型链上
    // console.log("name" in Tom);
    // console.log("color" in Tom);
    // console.log("species" in Tom);
    // console.log("a" in Tom);
    // console.log("toString" in Tom);

    // for(var key in Tom){}


    // propertyIsEnumerable()   判断某个实例化对象的属性是否可以枚举(被遍历) (只查找实例化对象自身,不查找原型链)
    // console.log(Tom.propertyIsEnumerable("name"));
    // console.log(Tom.propertyIsEnumerable("color"));
    // console.log(Tom.propertyIsEnumerable("type"));
    // console.log(Tom.propertyIsEnumerable("species"));  // false


    // isPrototypeOf()     判断某个构造函数的原型对象 是否存在于  实例化对象的原型链上

    // Tom -> Cat.prototype -> Object.prototype -> null
    // console.log(Cat.prototype.isPrototypeOf(Tom));
    // console.log(Object.prototype.isPrototypeOf(Tom));

    // 补充:
    // instanceOf  判断某个 实例化对象 的原型链上是否存在 某个构造函数 的原型对象
    console.log(Tom instanceof Cat);
    console.log(Tom instanceof Object);



</script>

</html>